using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using System.Xml.Xsl;


namespace Microsoft.ConnectionEngine.Common
{
    /// <summary>
    /// Utility class used to validate XML documents based on a schema file.
    /// </summary>
    public static class XmlValidator
    {
        private static bool IsValid;
        private static string FirstError = string.Empty;
        // Fix for WorkItem 159
        // Commented the method. 
        // Modified by Sajoshi : 23-Apr-2007

        //private static bool ValidteXml(string xmlfilename, ref string message, string schemaFileName)
        //{
        //    XmlDocument xmldoc = new XmlDocument();
        //    try
        //    {
        //        xmldoc.Load(xmlfilename);
        //    }
        //    catch
        //    {
        //        message = "Error Loading XML file.";
        //        return false;
        //    }
        //    return ValidateXml(xmldoc, ref message, schemaFileName);
        //}

        /// <summary>
        /// Validates an xml document based on a schema file.
        /// </summary>
        /// <param name="xmlstring">A string representing the xml content.</param>
        /// <param name="message">Any error message which is created during the validation.</param>
        /// <param name="schemaFileName">The schema file used to validate the xml document.</param>
        /// <returns>Returns a boolean indicating if the document is valid or not.</returns>
        public static bool ValidateXml(string xmlstring, ref string message, string schemaFileName)
        {
            XmlDocument xmldoc = new XmlDocument();
            try
            {
                xmldoc.LoadXml(xmlstring);
            }
            catch
            {
                message = "Error Loading XML string.";
                return false;
            }
            return ValidateXml(xmldoc, ref message, schemaFileName);
        }

        /// <summary>
        /// Validates an xml document based on a schema file.
        /// </summary>
        /// <param name="xmldoc">An object representing the xml document to be validated.</param>
        /// <param name="message">Any error message which is created during the validation.</param>
        /// <param name="schemaFileName">The schema file used to validate the xml document.</param>
        /// <returns></returns>
        public static bool ValidateXml(XmlDocument xmldoc, ref string message, string schemaFileName)
        {
            XmlSchemaCollection Schemas;
            Schemas = new XmlSchemaCollection();

            XmlUrlResolver urlresolver = new XmlUrlResolver();
            urlresolver.Credentials = System.Net.CredentialCache.DefaultCredentials;
            XmlReaderSettings xrsettings = new XmlReaderSettings();
            xrsettings.XmlResolver = urlresolver;
            XmlReader xr = XmlReader.Create(schemaFileName, xrsettings);

            Schemas.Add(null, xr);

            XmlTextReader tr = new XmlTextReader(xmldoc.OuterXml, XmlNodeType.Document, null);
            XmlValidatingReader rdr = new XmlValidatingReader(tr);

            rdr.ValidationType = ValidationType.Schema;
            rdr.Schemas.Add(Schemas);
            rdr.ValidationEventHandler += new ValidationEventHandler(ValidationCallBack);

            IsValid = true;
            FirstError = string.Empty;
            while (rdr.Read()) ;
            if (!IsValid) message = FirstError;
            return IsValid;
        }

        private static void ValidationCallBack(object sender, ValidationEventArgs e)
        {
            //Work Item Id: 1604
            //Modified By: SachinJo
            //if (FirstError == "") FirstError = e.Message;
            if (string.IsNullOrEmpty(FirstError)) FirstError = e.Message;
            IsValid = false;
        }
    }
}
